<!DOCTYPE html>
<html>
<head>
<title>ToDo API Client Demo</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet">
<script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.js"></script>
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-2.2.1.js"></script>
</head>
<body>
    <div class="navbar">
        <div class="navbar-inner">
            <a class="brand" href="#">ToDo API Client Demo</a>
        </div>
    </div>
    <div id="main" class="container">
        <table class="table table-striped">
            <tr><td style="width: 1px;"></td><td><b>Task</b></td><td><b>Options</b></td></tr>
            <!-- ko foreach: tasks -->
            <tr>
                <td>
                    <span data-bind="visible: done" class="label label-success">Done</span>
                    <span data-bind="visible: !done()" class="label label-important">In Progress</span>
                </td>
                <td><p><b data-bind="text: title"></b></p><p data-bind="text: description"></p></td>
                <td>
                    <button data-bind="click: $parent.beginEdit" class="btn">Edit</button>
                    <button data-bind="click: $parent.remove" class="btn">Delete</button>
                    <span data-bind="visible: done">
                        <button data-bind="click: $parent.markInProgress" class="btn">Mark In Progress</button>
                    </span>
                    <span data-bind="visible: !done()">
                        <button data-bind="click: $parent.markDone" class="btn">Mark Done</button>
                    </span>
                </td>
            </tr>
            <!-- /ko -->
        </table>
        <button data-bind="click: beginAdd" class="btn">Add Task</button>
    </div>
    <div id="add" class="modal hide fade" tabindex="=1" role="dialog" aria-labelledby="addDialogLabel" aria-hidden="true">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
            <h3 id="addDialogLabel">Add Task</h3>
        </div>
        <div class="modal-body">
            <form class="form-horizontal">
                <div class="control-group">
                    <label class="control-label" for="inputTask">Task</label>
                    <div class="controls">
                        <input data-bind="value: title" type="text" id="inputTask" placeholder="Task title" style="width: 150px;">
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="inputDescription">Description</label>
                    <div class="controls">
                        <input data-bind="value: description" type="text" id="inputDescription" placeholder="Description" style="width: 300px;">
                    </div>
                </div>
            </form>
        </div>
        <div class="modal-footer">
            <button data-bind="click: addTask" class="btn btn-primary">Add Task</button>
            <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
        </div>
    </div>
    <div id="edit" class="modal hide fade" tabindex="=1" role="dialog" aria-labelledby="editDialogLabel" aria-hidden="true">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
            <h3 id="editDialogLabel">Edit Task</h3>
        </div>
        <div class="modal-body">
            <form class="form-horizontal">
                <div class="control-group">
                    <label class="control-label" for="inputTask">Task</label>
                    <div class="controls">
                        <input data-bind="value: title" type="text" id="inputTask" placeholder="Task title" style="width: 150px;">
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="inputDescription">Description</label>
                    <div class="controls">
                        <input data-bind="value: description" type="text" id="inputDescription" placeholder="Description" style="width: 300px;">
                    </div>
                </div>
                <div class="control-group">
                    <div class="controls">
                        <label class="checkbox">
                            <input data-bind="checked: done" type="checkbox"> Done
                        </label>
                    </div>
                </div>
            </form>
        </div>
        <div class="modal-footer">
            <button data-bind="click:editTask" class="btn btn-primary">Update Task</button>
            <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
        </div>
    </div>
    <div id="login" class="modal hide fade" tabindex="=1" role="dialog" aria-labelledby="loginLabel" aria-hidden="true">
        <div class="modal-header">
            <h3 id="loginLabel">Sign In</h3>
        </div>
        <div class="modal-body">
            <form class="form-horizontal">
                <div class="control-group">
                    <label class="control-label" for="inputUsername">Username</label>
                    <div class="controls">
                        <input data-bind="value: username" type="text" id="inputUsername" placeholder="Username">
                    </div>
                </div>
                <div class="control-group">
                    <label class="control-label" for="inputPassword">Password</label>
                    <div class="controls">
                        <input data-bind="value: password" type="password" id="inputPassword" placeholder="Password">
                    </div>
                </div>
            </form>
        </div>
        <div class="modal-footer">
            <button data-bind="click: login" class="btn btn-primary" data-dismiss="modal" aria-hidden="true">Sign In</button>
        </div>
    </div>
    <script type="text/javascript">
        function TasksViewModel() {
            var self = this;
            self.tasksURI = 'http://localhost:5000/todo/api/v1.0/tasks';
            self.username = "";
            self.password = "";
            self.tasks = ko.observableArray();

            self.ajax = function(uri, method, data) {
                var request = {
                    url: uri,
                    type: method,
                    contentType: "application/json",
                    accepts: "application/json",
                    cache: false,
                    dataType: 'json',
                    data: JSON.stringify(data),
                    beforeSend: function (xhr) {
                        xhr.setRequestHeader("Authorization", 
                            "Basic " + btoa(self.username + ":" + self.password));
                    },
                    error: function(jqXHR) {
                        console.log("ajax error " + jqXHR.status);
                    }
                };
                return $.ajax(request);
            }
            self.updateTask = function(task, newTask) {
                var i = self.tasks.indexOf(task);
                self.tasks()[i].uri(newTask.uri);
                self.tasks()[i].title(newTask.title);
                self.tasks()[i].description(newTask.description);
                self.tasks()[i].done(newTask.done);
            }

            self.beginAdd = function() {
                $('#add').modal('show');
            }
            self.add = function(task) {
                self.ajax(self.tasksURI, 'POST', task).done(function(data) {
                    self.tasks.push({
                        uri: ko.observable(data.task.uri),
                        title: ko.observable(data.task.title),
                        description: ko.observable(data.task.description),
                        done: ko.observable(data.task.done)
                    });
                });
            }
            self.beginEdit = function(task) {
                editTaskViewModel.setTask(task);
                $('#edit').modal('show');
            }
            self.edit = function(task, data) {
                self.ajax(task.uri(), 'PUT', data).done(function(res) {
                    self.updateTask(task, res.task);
                });
            }
            self.remove = function(task) {
                self.ajax(task.uri(), 'DELETE').done(function() {
                    self.tasks.remove(task);
                });
            }
            self.markInProgress = function(task) {
                self.ajax(task.uri(), 'PUT', { done: false }).done(function(res) {
                    self.updateTask(task, res.task);
                });
            }
            self.markDone = function(task) {
                self.ajax(task.uri(), 'PUT', { done: true }).done(function(res) {
                    self.updateTask(task, res.task);
                });
            }
            self.beginLogin = function() {
                $('#login').modal('show');
            }
            self.login = function(username, password) {
                self.username = username;
                self.password = password;
                self.ajax(self.tasksURI, 'GET').done(function(data) {
                    for (var i = 0; i < data.tasks.length; i++) {
                        self.tasks.push({
                            uri: ko.observable(data.tasks[i].uri),
                            title: ko.observable(data.tasks[i].title),
                            description: ko.observable(data.tasks[i].description),
                            done: ko.observable(data.tasks[i].done)
                        });
                    }
                }).fail(function(jqXHR) {
                    if (jqXHR.status == 403)
                        setTimeout(self.beginLogin, 500);
                });
            }
            
            self.beginLogin();
        }
        function AddTaskViewModel() {
            var self = this;
            self.title = ko.observable();
            self.description = ko.observable();
 
            self.addTask = function() {
                $('#add').modal('hide');
                tasksViewModel.add({
                    title: self.title(),
                    description: self.description()
                });
                self.title("");
                self.description("");
            }
        }
        function EditTaskViewModel() {
            var self = this;
            self.title = ko.observable();
            self.description = ko.observable();
            self.done = ko.observable();
 
            self.setTask = function(task) {
                self.task = task;
                self.title(task.title());
                self.description(task.description());
                self.done(task.done());
                $('edit').modal('show');
            }
 
            self.editTask = function() {
                $('#edit').modal('hide');
                tasksViewModel.edit(self.task, {
                    title: self.title(),
                    description: self.description() ,
                    done: self.done()
                });
            }
        }
        function LoginViewModel() {
            var self = this;
            self.username = ko.observable();
            self.password = ko.observable();
 
            self.login = function() {
                $('#login').modal('hide');
                tasksViewModel.login(self.username(), self.password());
            }
        }
        
        var tasksViewModel = new TasksViewModel();
        var addTaskViewModel = new AddTaskViewModel();
        var editTaskViewModel = new EditTaskViewModel();
        var loginViewModel = new LoginViewModel();
        ko.applyBindings(tasksViewModel, $('#main')[0]);
        ko.applyBindings(addTaskViewModel, $('#add')[0]);
        ko.applyBindings(editTaskViewModel, $('#edit')[0]);
        ko.applyBindings(loginViewModel, $('#login')[0]);
    </script>
</body>
</html>
